package com.hanson.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;


/**
 * @CLassName MybatisPlusTemplateConfig
 * @Description mybatis-plus代码生成模板设置
 * @Author HansonLee
 * @Date 2020/10/29 17:16
 **/
@Component
public class MybatisPlusTemplateConfig {

    @Autowired
    private MybatisPlusProperties mpProperties;


    /**
     *
     * 代码生成器
     *
     * @param
     * @return {@link AutoGenerator}
     * @author HansonLee
     * @date 2020/10/29 17:48
     **/
    public AutoGenerator autoGenerator(){
        return autoGenerator(new VelocityTemplateEngine());
    }

    public AutoGenerator autoGenerator(AbstractTemplateEngine templateEngine){
        AutoGenerator agt = new AutoGenerator();
        agt.setGlobalConfig(globalConfig());
        agt.setDataSource(dataSourceConfig());
        agt.setPackageInfo(packageConfig());
        agt.setStrategy(strategyConfig());
        agt.setTemplate(templateConfig());
        agt.setTemplateEngine(templateEngine);
        System.out.println("111111111111111111111");
        return agt;
    }

    /**
     *
     * 全局配置
     *
     * @param
     * @return {@link GlobalConfig}
     * @author HansonLee
     * @date 2020/10/29 17:20
     **/
    public GlobalConfig globalConfig(){
        if (mpProperties.getMybatisPlus().getProjectPath() != null) {
            return globalConfig(mpProperties.getMybatisPlus().getProjectPath());
        }
        return globalConfig(mpProperties.getMybatisPlus().getDefaultProjectPath());
    }

    public GlobalConfig globalConfig(String projectPath){
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(projectPath);
        gc.setFileOverride(true);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        //覆盖先前的文件
        gc.setFileOverride(true);
        gc.setAuthor(mpProperties.getMybatisPlus().getAuthor());
        gc.setOpen(false);
        //实体属性 Swagger2 注解
        gc.setSwagger2(true);
        return gc;
    }

    /**
     *
     * 数据源配置
     *
     * @param
     * @return {@link DataSourceConfig}
     * @author HansonLee
     * @date 2020/10/29 17:25
     **/
    public DataSourceConfig dataSourceConfig(){
        DataSourceConfig dsc = new DataSourceConfig();
        //指定oracle数据库类型
        if (mpProperties.getMybatisPlus().getIfOracle()){
            dsc.setDbType(DbType.ORACLE);
        }else {
            dsc.setDbType(DbType.MYSQL);
        }
//        dsc.setSchemaName("bv");
        dsc.setUrl(mpProperties.getMybatisPlus().getUrl());
        dsc.setDriverName(mpProperties.getMybatisPlus().getDriver());
        dsc.setUsername(mpProperties.getMybatisPlus().getUserName());
        dsc.setPassword(mpProperties.getMybatisPlus().getPassword());
        return dsc;
    }

    /**
     *
     * 包配置
     *
     * @param
     * @return {@link PackageConfig}
     * @author HansonLee
     * @date 2020/10/29 17:27
     **/
    public PackageConfig packageConfig(){
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(mpProperties.getMybatisPlus().getModuleName());
        pc.setParent(mpProperties.getMybatisPlus().getParent());
        pc.setEntity(mpProperties.getMybatisPlus().getEntityUrl());
        pc.setMapper(mpProperties.getMybatisPlus().getMapperUrl());
        pc.setXml(mpProperties.getMybatisPlus().getXmlUrl());
        pc.setService(mpProperties.getMybatisPlus().getServiceUrl());
        pc.setServiceImpl(mpProperties.getMybatisPlus().getServiceImplUrl());
        pc.setController(mpProperties.getMybatisPlus().getControllerUrl());
        return pc;
    }

    /**
     *
     * 自定义配置
     *
     * @param
     * @return {@link InjectionConfig}
     * @author HansonLee
     * @date 2020/10/29 17:28
     **/
    public InjectionConfig injectionConfig(){
        return new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
    }

    /**
     *
     * 配置自定义输出模板
     *
     * @param
     * @return {@link TemplateConfig}
     * @author HansonLee
     * @date 2020/10/29 17:39
     **/
    public TemplateConfig templateConfig(){
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(mpProperties.getMybatisPlus().getXmlTemplatePath());
        templateConfig.setMapper(mpProperties.getMybatisPlus().getMapperTemplatePath());
        templateConfig.setEntity(mpProperties.getMybatisPlus().getEntityTemplatePath());
        templateConfig.setService(mpProperties.getMybatisPlus().getServiceTemplatePath());
        templateConfig.setServiceImpl(mpProperties.getMybatisPlus().getServiceImplTemplatePath());
        templateConfig.setController(mpProperties.getMybatisPlus().getControllerTemplatePath());
        return templateConfig;
    }

    /**
     *
     * 策略配置
     *
     * @param
     * @return {@link StrategyConfig}
     * @author HansonLee
     * @date 2020/10/29 17:42
     **/
    public StrategyConfig strategyConfig(){
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//        strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父类
//        strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
        // 写于父类中的公共字段，例如表id字段等
//        strategy.setSuperEntityColumns("id");
        if (mpProperties.getMybatisPlus().getInclude() != null){
            String include = mpProperties.getMybatisPlus().getInclude();
            //数据库表必须大写
            if (mpProperties.getMybatisPlus().getIfOracle())
                include = include.toUpperCase();
            String[] result = include.split(",");
            strategy.setInclude(result);
        }
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(packageConfig().getModuleName() + "_");
        strategy.setEntityTableFieldAnnotationEnable(true);
        strategy.setEntitySerialVersionUID(true);
        return strategy;
    }

    /**
     *
     * 自定义配置
     *
     * @param mptc
     * @return {@link MybatisPlusTemplateConfig}
     * @author HansonLee
     * @date 2020/10/29 17:31
     **/
    public MybatisPlusTemplateConfig mybatisPlusTemplateConfig(MybatisPlusTemplateConfig mptc){
        //自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出,自定义xml输出配置
        focList.add(new FileOutConfig(mpProperties.getMybatisPlus().getXmlTemplatePath()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                String parent = mptc.packageConfig().getParent();
                String[] split = parent.split("\\.");
                StringBuilder sbd = new StringBuilder();
                sbd.append(mpProperties.getMybatisPlus().getDefaultProjectPath());
                for (int i = 0; i < split.length; i++) {
                    sbd.append(split[i]).append("/");
                }
                sbd.append(mptc.packageConfig().getMapper()).append("/");
                String path = sbd.toString();
                return path + "/mapping"
                        + "/" + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        return mptc;
    }
}
